import 'dart:convert';
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:aitao_flutter/common_ui/loading_view.dart';
import 'package:aitao_flutter/const/common_const.dart';
import 'package:aitao_flutter/model/im/socket_params_model.dart';
import 'package:aitao_flutter/utils/sp_utils.dart';
import 'package:aitao_flutter/utils/time_utils.dart';
import 'package:aitao_flutter/video_chat/views/video_request_page.dart';
import 'package:aitao_flutter/video_chat/views/video_response_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:nim_core/nim_core.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../websocket/websocket_manager.dart';
import '../controller/video_chat_controller.dart';
import 'package:web_socket_channel/io.dart';

// import 'package:web_socket_channel/status.dart' as status;
class VideoChatPage extends StatefulWidget {
  const VideoChatPage({super.key});

  @override
  State<VideoChatPage> createState() => _VideoChatPageState();
}

class _VideoChatPageState extends State<VideoChatPage> {
  VideoChatController chatController = Get.put(VideoChatController());
  IOWebSocketChannel? channel;
  bool showView = false;

  WebSocketManager? manager;

  int? _remoteUid;
  bool _localUserJoined = false;
  late RtcEngine _engine;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    manager = WebSocketManager(
        url: chatController.model?.socketUrl ?? '',
        roomId: chatController.model?.roomId ?? '',
        socketCloseCallBack: () {
          if (chatController.type == ChatStringConst.videoRequestPage) {
            debugPrint('Socket关闭后要取消拨打视图');
          } else {
            debugPrint('Socket关闭后要取消来电视图');
          }
          EasyLoading.showToast('对方拒绝视频');
          Get.back();
        },
        requestSuccessCallBack: () {},
        responseConnentCallBack: () {
          debugPrint('responseConnentCallBack');
        },
        responseChoosingCallBack: (int tip) {
          debugPrint('responseChoosingCallBack:$tip');
        },
        videoEndCallBack: (type) {
          debugPrint('videoEndCallBack:$type');
        },
        videoStartCallBack: (SocketData data) async {
          debugPrint('videoStartCallBack:${data.toString()}');
          debugPrint('主叫方连接成功,关闭拨打页面,发送IM自定义消息,开始视频聊天');
          setState(() {
            showView = true;
          });

          Map map = {
            'id': 1,
            'data': {
              'roomid': chatController.model?.roomId,
              'callTime': TimeUtils.getCurrentTimestamp()
            }
          };
          String mapJson = json.encode(map);
          // 配置 CustomNotificationConfig
          CustomNotificationConfig config = CustomNotificationConfig(
              enablePush: true, enableUnreadCount: true);
          // 构造自定义通知，指定接收者
          CustomNotification notification = CustomNotification(
              sessionId: chatController.model?.toUid.toString(),
              sessionType: NIMSessionType.p2p,
              content: mapJson,
              config: config);
          final result = await NimCore.instance.systemMessageService
              .sendCustomNotification(notification);
          debugPrint('result:$result');
          await _engine.joinChannel(
            token: chatController.model?.agoraToken ?? '',
            channelId: chatController.model?.roomId ?? '',
            uid: SpUtil.getUserData().userinfo!.userId!,
            options: const ChannelMediaOptions(),
          );
        },
        reciveTxtCallBack: (tip) {
          debugPrint('reciveTxtCallBack:$tip');
        },
        canCallTimeCallBack: (int tip) {
          debugPrint('canCallTimeCallBack:$tip');
        },
        accountcoinsCallBack: (coin) {
          debugPrint('accountcoinsCallBack:$coin');
        },
        autoHangUpCallBack: () {});
    manager?.connect();
    initAgora();
  }

  Future<void> initAgora() async {
    // retrieve permissions
    await [Permission.microphone, Permission.camera].request();

    //create the engine
    _engine = createAgoraRtcEngine();
    await _engine.initialize(const RtcEngineContext(
      appId: '40134fdc1c4b47de8e2f51f16b334f3e',
      channelProfile: ChannelProfileType.channelProfileLiveBroadcasting,
    ));

    _engine.registerEventHandler(
      RtcEngineEventHandler(
        onJoinChannelSuccess: (RtcConnection connection, int elapsed) {
          debugPrint("local user ${connection.localUid} joined");
          setState(() {
            _localUserJoined = true;
          });
        },
        onUserJoined: (RtcConnection connection, int remoteUid, int elapsed) {
          debugPrint("remote user $remoteUid joined");
          setState(() {
            _remoteUid = remoteUid;
          });
        },
        onUserOffline: (RtcConnection connection, int remoteUid,
            UserOfflineReasonType reason) {
          debugPrint("remote user $remoteUid left channel");
          setState(() {
            _remoteUid = null;
          });
        },
        onTokenPrivilegeWillExpire: (RtcConnection connection, String token) {
          debugPrint(
              '[onTokenPrivilegeWillExpire] connection: ${connection.toJson()}, token: $token');
        },
      ),
    );

    await _engine.setClientRole(role: ClientRoleType.clientRoleBroadcaster);
    await _engine.enableVideo();
    await _engine.startPreview();
  }

  @override
  void dispose() {
    super.dispose();
    _dispose();
  }

  Future<void> _dispose() async {
    await _engine.leaveChannel();
    await _engine.release();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: chatController.model == null
            ? const LoadingView()
            : GetBuilder<VideoChatController>(builder: (controller) {
                return Container(
                  color: const Color(0xFF5E5858),
                  child: Stack(
                    children: [
                      Visibility(
                        visible: showView,
                        replacement:
                            controller.type == ChatStringConst.videoRequestPage
                                ? VideoRequestPage(
                                    hangupCallBack: () {
                                      manager?.sendCancel();
                                      // setState(() {
                                      //   showView = true;
                                      // });
                                      EasyLoading.showToast('取消视频');
                                      Get.back();
                                    },
                                    userId: chatController.model?.toUid ?? 0,
                                  )
                                : VideoResponsePage(
                                    hangupCallBack: () {
                                      debugPrint('拒绝');
                                      setState(() {
                                        showView = true;
                                      });
                                    },
                                    answerCallBack: () {
                                      debugPrint('接听');
                                      setState(() {
                                        showView = true;
                                      });
                                    },
                                  ),
                        child: Stack(
                          children: [
                            Center(
                              child: _remoteVideo(),
                            ),
                            Align(
                              alignment: Alignment.topLeft,
                              child: SizedBox(
                                width: 100,
                                height: 150,
                                child: Center(
                                  child: _localUserJoined
                                      ? AgoraVideoView(
                                          controller: VideoViewController(
                                            rtcEngine: _engine,
                                            canvas: const VideoCanvas(uid: 0),
                                          ),
                                        )
                                      : const CircularProgressIndicator(),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                );
              }));
  }

  Widget _remoteVideo() {
    if (_remoteUid != null) {
      return AgoraVideoView(
        controller: VideoViewController.remote(
          rtcEngine: _engine,
          canvas: VideoCanvas(uid: _remoteUid),
          connection: RtcConnection(channelId: chatController.model?.roomId),
        ),
      );
    } else {
      return const Text(
        'Please wait for remote user to join',
        textAlign: TextAlign.center,
      );
    }
  }
}
